/**
 * @description 封装http请求功能
 * @author 张立
 */

import axios from 'axios'
import qs from 'qs'
import { message } from 'ant-design-vue'
import Vue from 'vue'
let loading
message.config({
  maxCount: 1,
  top: '25px',
  duration: 2,
})
const vm = new Vue()

// 请求超时时间
axios.defaults.timeout = 15000
axios.defaults.withCredentials = true // 让ajax携带cookie
// 设置公用请求头
// 拦截请求
axios.interceptors.request.use(
  function (config) {
    return config
  },
  function (error) {
    return Promise.reject(error)
  }
)

// 拦截响应
axios.interceptors.response.use(
  function (response) {
    return response
  },
  function (error) {
    return Promise.reject(error)
  }
)

const showToast = (tip = '加载中...') => {
  loading = vm.$message.loading(tip, 0)
}

// 处理响应结果
function responseRes(res) {
  // 清除加载
  setTimeout(loading, 0)
  return new Promise((resolve) => {
    if (res.code === 200 || res.status === true || res.status === 200) {
      resolve(res)
    } else if (res.code === 401) {
      vm.$message.warning('数据认证失败')
    } else {
      vm.$message.warning('数据请求失败')
    }
  })
}

/**
 * 服务器返回异常处理
 */
const errorTip = (err) => {
  setTimeout(loading, 0)
  let msg = '服务异常，请重新尝试'
  return new Promise((resolve) => {
    if (err.response) {
      if (err.response.status === 401) {
        msg = '登录超时,请重新登录'
      } else {
        msg = err.response.data.message || '服务异常，请重新尝试'
      }
    } else {
      msg = '服务异常，请重新尝试'
    }
    vm.$message.warning(msg)
    // eslint-disable-next-line prefer-promise-reject-errors
    resolve('error')
  })
}

const $http = {
  async get(obj, tag = true) {
    if (tag) showToast()
    try {
      let res = await axios.get(obj.url, {
        params: obj.params || '',
      })
      res = res.data
      return responseRes(res)
    } catch (err) {
      return errorTip(err)
    }
  },
  async getUrl(obj, tag = true) {
    if (tag) showToast()
    try {
      let res = await axios.get(obj.url, {})
      res = res.data
      return responseRes(res)
    } catch (err) {
      return errorTip(err)
    }
  },
  async postForm(obj, tag = true) {
    if (tag) showToast()
    try {
      let res = await axios.post(obj.url, qs.stringify(obj.params))
      res = res.data
      return responseRes(res)
    } catch (err) {
      return errorTip(err)
    }
  },
  async post(obj, tag = true) {
    if (tag) showToast()
    try {
      let res = await axios({
        url: obj.url,
        method: 'post',
        data: obj.params,
        headers: {
          'Content-Type': 'application/json',
        },
      })
      res = res.data
      return responseRes(res)
    } catch (err) {
      return errorTip(err)
    }
  },
  async postJsonQuery(obj, tag = true) {
    if (tag) showToast()
    let url = obj.url + '?'
    for (const key in obj.params) {
      url += key + '=' + obj.params[key] + '&'
    }
    try {
      let res = await axios({
        url,
        method: 'post',
        data: obj.params,
        headers: {
          'Content-Type': 'application/json',
        },
      })
      res = res.data
      return responseRes(res)
    } catch (err) {
      return errorTip(err)
    }
  },
  async postQuery(obj, tag = true) {
    if (tag) showToast()
    let url = obj.url + '?'
    for (const key in obj.params) {
      url += key + '=' + obj.params[key] + '&'
    }
    try {
      let res = await axios.post(url, qs.stringify({}))
      res = res.data
      return responseRes(res)
    } catch (err) {
      return errorTip(err)
    }
  },
}

export default $http
